﻿using System;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;

namespace Span_Down_Sharp
{
    /// <summary>
    /// 接收输入
    /// </summary>
    public class Input
    {
        /// <summary>
        /// 接收是否输入
        /// </summary>
        public static bool Read_YesOrNo(string message, bool? defaultValue = null)
        {
            while (true)
            {
                Console.Write(message);
                var input = Console.ReadLine();
                if (!string.IsNullOrWhiteSpace(input))
                {
                    input = input.Trim().ToLower();
                    if (input == "y" || input == "n")
                    {
                        return input == "y";
                    }
                }

                if (defaultValue != null)
                    return defaultValue.Value;
            }
        }

        /// <summary>
        /// 接收文本输入
        /// </summary>
        public static string Read_Text(string message, string defaultValue = null)
        {
            while (true)
            {
                Console.Write(message);
                var input = Console.ReadLine();
                if (!string.IsNullOrWhiteSpace(input))
                    return input.Trim();

                if (defaultValue != null)
                    return defaultValue;
            }
        }

        /// <summary>
        /// 接收整数输入
        /// </summary>
        public static int Read_Integer(string message, int minValue = Int32.MinValue, int maxValue = Int32.MaxValue)
        {
            var defaultMessage = message;
            while (true)
            {
                Console.Write(message);
                var input = Console.ReadLine();
                if (string.IsNullOrWhiteSpace(input))
                {
                    message = defaultMessage;
                    continue;
                }

                input = input.Trim();
                int result;
                if (!Int32.TryParse(input, out result))
                {
                    message = "必须输入一个整数: ";
                    continue;
                }
                else if (result < minValue || result > maxValue)
                {
                    message = $"整数范围必须是 {minValue}-{maxValue}，请重新输入: ";
                    continue;
                }

                return result;
            }
        }

        /// <summary>
        /// 接收URL输入
        /// </summary>
        public static string Read_Url(string message, string defaultValue = null)
        {
            var defaultMessage = message;
            while (true)
            {
                Console.Write(message);
                var input = Console.ReadLine();
                if (string.IsNullOrWhiteSpace(input))
                {
                    if (defaultValue != null)
                        return defaultValue;

                    message = defaultMessage;
                    continue;
                }

                input = input.Trim();
                if (input.Length < 18 ||
                    !(input.StartsWith("http://", StringComparison.OrdinalIgnoreCase) ||
                    input.StartsWith("https://", StringComparison.OrdinalIgnoreCase)))
                {
                    message = "URL格式不正确，请重新输入: ";
                    continue;
                }

                return input;
            }
        }

        /// <summary>
        /// 接收目录输入
        /// </summary>
        public static string Read_Path(string message, string defaultValue = null, bool createIfNotExist = true)
        {
            string defaultMessage = message;
            string path = null;
            while (true)
            {
                Console.Write(message);
                var input = Console.ReadLine();
                if (!string.IsNullOrWhiteSpace(input))
                {
                    path = input.Trim();
                }
                else if (defaultValue != null)
                {
                    path = defaultValue;
                }
                else
                {
                    message = defaultMessage;
                    continue;
                }

                try
                {
                    var dir = NewDirectoryInfo(path);         // 新建DirectoryInfo对象，如果抛出异常说明路径非法          
                    if (createIfNotExist && !dir.Exists)
                    {
                        dir.Create();
                        path = dir.FullName;
                    }
                }
                catch (ArgumentException)
                {
                    message = "该路径不合法，请重新输入: ";
                    path = null;
                    continue;
                }
                catch (PathTooLongException)
                {
                    message = "该路径长度超过系统定义最大值，请重新输入: ";
                    path = null;
                    continue;
                }
                return path;
            }
        }

        static DirectoryInfo NewDirectoryInfo(string path)
        {
            if (string.IsNullOrWhiteSpace(path))
                throw new ArgumentNullException("path");

            var invalidPathChars = Path.GetInvalidPathChars();
            var pathMaxLength = 1024;
            var pathNoRoot = path;
            if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
            {
                invalidPathChars = invalidPathChars.Append('>').Append('<').Append('*').Append('?').Append('"').Append(':').ToArray();
                pathMaxLength = 255;
                var pathRoot = Path.GetPathRoot(path);  // D:\ C:\
                if (!string.IsNullOrWhiteSpace(pathRoot) && path.Length > pathRoot.Length)
                {
                    pathNoRoot = path.Substring(pathRoot.Length);
                }
            }

            if (pathNoRoot.IndexOfAny(invalidPathChars) > -1)
                throw new ArgumentException();

            if (pathNoRoot.Length > pathMaxLength)
                throw new PathTooLongException();

            return new DirectoryInfo(path);
        }
    }
}
